package com.nb.verticaldraglistview;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.customview.widget.ViewDragHelper;

/**
 * Created by DongKing on 2020/11/19
 * Version 1.0
 * Describe:
 * 1.后面的不可以滑动，前面的可以滑动
 * 2.只能上下滑动
 * 3.滑动的高度不可以超过 menu的高度，
 * 4.只有打开和关闭两种状态，中间状态松手，根据距离判断去到哪一种状态
 */
class VerticalDragListView extends FrameLayout {
    private static final String TAG = "VerticalDragListView";

    private ViewDragHelper mDragHelper;
    private View mMenuView;
    private View mDragView;
    private int mMenuHeight;
    private boolean isOpen = false;

    public VerticalDragListView(@NonNull Context context) {
        this(context, null);
    }

    public VerticalDragListView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public VerticalDragListView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mDragHelper = ViewDragHelper.create(this, mDragCallback);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mMenuView = getChildAt(0);
        mDragView = getChildAt(1);


    }

    ViewDragHelper.Callback mDragCallback = new ViewDragHelper.Callback() {
        @Override
        public boolean tryCaptureView(@NonNull View child, int pointerId) {
            //只有mDragView 可以滑动
            return mDragView == child;
        }

        @Override
        public int clampViewPositionVertical(@NonNull View child, int top, int dy) {
            //通过top 控制范围
            if (top < 0) {
                top = 0;
            }
            if (top > mMenuHeight) {
                top = mMenuHeight;
            }
            return top;
        }

        @Override
        public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {
            int dy = mDragView.getTop();
            //当手指松开的时候
            if (dy > mMenuHeight / 2) {
                //打开
                mDragHelper.settleCapturedViewAt(0, mMenuHeight);
                isOpen = true;
            } else {
                //关闭
                mDragHelper.settleCapturedViewAt(0, 0);
                isOpen = false;
            }

            invalidate();
        }
    };

    @Override
    public void computeScroll() {
        if (mDragHelper.continueSettling(true)) {
            invalidate();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mMenuHeight = mMenuView.getMeasuredHeight();
    }


    float downY = 0;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (isOpen) {
            return true;
        }

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDragHelper.processTouchEvent(ev);
                downY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                //子view滑动到顶部
                if (ev.getY() - downY > 0 && !canChildScrollUp(mDragView)) {
                    return true;
                }
                break;
        }

        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mDragHelper.processTouchEvent(event);
        return true;
    }

    public boolean canChildScrollUp(View mTarget) {

        if (android.os.Build.VERSION.SDK_INT < 14) {
            if (mTarget instanceof AbsListView) {
                final AbsListView absListView = (AbsListView) mTarget;
                return absListView.getChildCount() > 0
                        && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
                        .getTop() < absListView.getPaddingTop());
            } else {
                return mTarget.canScrollVertically(-1) || mTarget.getScrollY() > 0;
            }
        } else {
            return mTarget.canScrollVertically(-1);
        }
    }
}
